#include <grpc/grpc.h>
#include <grpcpp/channel.h>
#include <grpcpp/client_context.h>
#include <grpcpp/create_channel.h>
#include <grpcpp/security/credentials.h>

#include <algorithm>
#include <chrono>
#include <cmath>
#include <iostream>
#include <memory>
#include <string>

#include "hello.grpc.pb.h"
#include "hello.pb.h"

using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::ServerReader;
using grpc::ServerReaderWriter;
using grpc::ServerWriter;
using grpc::Status;
using std::chrono::system_clock;

using namespace grpc;
using namespace hello;
using namespace std;

int main(int argc, char** argv) {
  unique_ptr<ExampleService::Stub> stub =
      ExampleService::NewStub(grpc::CreateChannel(
          "localhost:50051", grpc::InsecureChannelCredentials()));
  {
    ClientContext context;
    HelloRequest request;
    request.set_name(0);
    HelloResponse response;
    Status status = stub->SayHi(&context, request, &response);
    if (!status.ok()) {
      std::cout << "SayHi rpc failed." << std::endl;
      return false;
    }
    cout << "sayHi return " << response.message() << endl;
  }

  {
    ClientContext context;
    HelloRequest request;
    request.set_name(1);
    HelloResponse response;

    std::unique_ptr<ClientReader<HelloResponse> > reader(
        stub->SayHiStreamly(&context, request));
    {
      {
        ClientContext context1;
        HelloRequest request1;
        request1.set_name(2);
        HelloResponse response1;
        Status status1 = stub->SayHi(&context1, request1, &response1);
        if (!status1.ok()) {
          std::cout << "SayHi rpc failed." << std::endl;
          return false;
        }
        cout << "sayHi return " << response1.message() << endl;
      }
    }
    while (reader->Read(&response)) {
      cout << "sayHiStreamly return " << response.message() << endl;
    }
    Status status = reader->Finish();
    if (status.ok()) {
      std::cout << "sayHiStreamly rpc succeeded." << std::endl;
    } else {
      std::cout << "sayHiStreamly rpc failed." << std::endl;
    }
  }

  return 0;
}
